namespace AwesomiumDotNet
{
	/// <summary>
	/// Windows keyboard messages,
	/// used with WebView.InjectKeyboardEvent
	/// </summary>
	public enum class WM : Int32
	{
		KeyDown = WM_KEYDOWN,
		KeyUp = WM_KEYUP,
		Char = WM_CHAR,
		DeadChar = WM_DEADCHAR,
		SysKeyDown = WM_SYSKEYDOWN,
		SysKeyUp = WM_SYSKEYUP,
		SysChar = WM_SYSCHAR,
		SysDeadChar = WM_SYSDEADCHAR,
		UniChar = WM_UNICHAR,
		KeyFirst = WM_KEYFIRST,
		KeyLast = WM_KEYLAST,
	};

#ifndef VERSION_108

	/// <summary>
	/// An enumeration of the different WebKeyboardEvent types.
	/// </summary>
	public enum class KeyboardEventType
	{
		/// <summary>Key-Down type</summary>
		KeyDownType = Awesomium::WebKeyboardEvent::TYPE_KEY_DOWN,
		/// <summary>Key-Up type</summary>
		KeyUpType = Awesomium::WebKeyboardEvent::TYPE_KEY_UP,
		/// <summary>Character input type</summary>
		CharType = Awesomium::WebKeyboardEvent::TYPE_CHAR
	};

	/// <summary>
	/// An enumeration of the different keyboard modifiers.
	/// </summary>
	[Flags]
	public enum class Modifiers
	{
		/// <summary>No modifiers</summary>
		None = 0,
		/// <summary>Whether or not a Shift key is down</summary>
		ShiftKey = Awesomium::WebKeyboardEvent::MOD_SHIFT_KEY,
		/// <summary>Whether or not a Control key is down</summary>
		ControlKey = Awesomium::WebKeyboardEvent::MOD_CONTROL_KEY,
		/// <summary>Whether or not an Alt key is down</summary>
		AltKey = Awesomium::WebKeyboardEvent::MOD_ALT_KEY,
		/// <summary>Whether or not a meta key (Windows-key on Windows) is down</summary>
		MetaKey = Awesomium::WebKeyboardEvent::MOD_META_KEY,
		/// <summary>Whether or not the key pressed is on the keypad</summary>
		KeyPad = Awesomium::WebKeyboardEvent::MOD_IS_KEYPAD,
		/// <summary>Whether or not the character input is the result of an auto-repeat timer.</summary>
		AutoRepeat = Awesomium::WebKeyboardEvent::MOD_IS_AUTOREPEAT,
	};

	/// <summary>
	/// A generic keyboard event that can be created from a platform-specific event or
	/// synthesized from a virtual event. Used by WebView.InjectKeyboardEvent.
	/// </summary>
	public ref class WebKeyboardEvent
	{
	private:
		Awesomium::WebKeyboardEvent* keyboardEvent;

	public:
		/// <summary>
		/// The type of this WebKeyboardEvent.
		/// </summary>
		property KeyboardEventType EventType
		{
			KeyboardEventType get()
			{
				return (KeyboardEventType)keyboardEvent->type;
			}
			void set(KeyboardEventType value)
			{
				keyboardEvent->type = (Awesomium::WebKeyboardEvent::Type)value;
			}
		}

		/// <summary>
		/// Whether or not the pressed key is a "system key".
		/// For more information, see the following
		/// link: http://msdn.microsoft.com/en-us/library/ms646286(VS.85).aspx
		/// </summary>
		property bool IsSystemKey
		{
			bool get() { return keyboardEvent->isSystemKey; }
			void set(bool value) { keyboardEvent->isSystemKey = value; }
		}

		/// <summary>
		/// The current state of the keyboard. Modifiers may be OR'd together to represent multiple values.
		/// </summary>
		property AwesomiumDotNet::Modifiers Modifiers
		{
			AwesomiumDotNet::Modifiers get()
			{
				return (AwesomiumDotNet::Modifiers)keyboardEvent->modifiers;
			}
			void set(AwesomiumDotNet::Modifiers value)
			{
				keyboardEvent->modifiers = (int)value;
			}
		}

		/// <summary>
		/// The virtual key-code associated with this keyboard event. This is either directly
		/// from the event (ie, WPARAM on Windows) or via a mapping function.
		/// </summary>
		property int VirtualKeyCode
		{
			int get() { return keyboardEvent->virtualKeyCode; }
			void set(int value) { keyboardEvent->virtualKeyCode = value; }
		}

		/// <summary>
		/// The actual key-code generated by the platform. The DOM specification primarily uses
		/// Windows-equivalent codes (hence virtualKeyCode above) but it helps to additionally
		/// specify the platform-specific key-code as well.
		/// </summary>
		property int NativeKeyCode
		{
			int get() { return keyboardEvent->nativeKeyCode; }
			void set(int value) { keyboardEvent->nativeKeyCode = value; }
		}

		/// <summary>
		/// The actual text generated by this keyboard event.
		/// </summary>
		property int Text
		{
			int get() { return keyboardEvent->text[0]; }
			void set(int value) { keyboardEvent->text[0] = value; }
		}

		/// <summary>
		/// The text generated by this keyboard event before all modifiers except shift are applied.
		/// This is used internally for working out shortcut keys.
		/// </summary>
		property int UnmodifiedText
		{
			int get() { return keyboardEvent->unmodifiedText[0]; }
		}

		/// <summary>
		/// Creates an empty WebKeyboardEvent, you will need to initialize its members
		/// yourself. This is most useful for synthesizing your own keyboard events.
		/// </summary>
		WebKeyboardEvent()
		{
			keyboardEvent = new Awesomium::WebKeyboardEvent();
		}

		/// <summary>
		/// Creates a WebKeyboardEvent directly from a Windows keyboard event message.
		/// </summary>
		WebKeyboardEvent(WM msg, WPARAM wParam, LPARAM lParam)
		{
			keyboardEvent = new Awesomium::WebKeyboardEvent((UINT)msg, wParam, lParam);
		}

		/// <summary>
		/// Creates a WebKeyboardEvent directly from a Windows keyboard event message.
		/// </summary>
		WebKeyboardEvent(UINT msg, WPARAM wParam, LPARAM lParam)
		{
			keyboardEvent = new Awesomium::WebKeyboardEvent(msg, wParam, lParam);
		}

		/// <summary>
		/// Creates a WebKeyboardEvent directly from a Windows keyboard event message.
		/// </summary>
		WebKeyboardEvent(Message message)
		{
			keyboardEvent = new Awesomium::WebKeyboardEvent(message.Msg,
				(WPARAM)message.WParam.ToPointer(),
				(LPARAM)message.LParam.ToPointer()
				);
		}

	internal:
		Awesomium::WebKeyboardEvent ToNative()
		{
			return *keyboardEvent;
		}
	};

#endif
};
